<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>3.&nbsp;消息通道</title>
<link rel="stylesheet" href="css/manual.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
<link rel="home" href="index.html"
	title="Spring Integration Reference Manual">
<link rel="up" href="spring-integration-core-messaging.html"
	title="Part&nbsp;III.&nbsp;Core Messaging">
<link rel="prev" href="spring-integration-core-messaging.html"
	title="Part&nbsp;III.&nbsp;Core Messaging">
<link rel="next" href="messaging-construction-chapter.html"
	title="4.&nbsp;Message Construction">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084"
	alink="#0000FF">
	<div class="navheader">
		<table width="100%" summary="Navigation header">
			<tr>
				<th colspan="3" align="center">3.&nbsp;消息通道</th>
			</tr>
			<tr>
				<td width="20%" align="left"><a accesskey="p"
					href="spring-integration-core-messaging.html">上一页</a>&nbsp;</td>
				<th width="60%" align="center">第三部分：核心消息处理</th>
				<td width="20%" align="right">&nbsp;<a accesskey="n"
					href="messaging-construction-chapter.html">下一页</a></td>
			</tr>
		</table>
		<hr>
	</div>
	<div class="chapter" title="3.&nbsp;消息通道">
		<div class="titlepage">
			<div>
				<div>
					<h2 class="title">
						<a name="messaging-channels-section"></a>3.&nbsp;消息通道
					</h2>
				</div>
			</div>
		</div>


		<div class="section" title="3.1&nbsp;消息通道">
			<div class="titlepage">
				<div>
					<div>
						<h2 class="title" style="clear: both">
							<a name="channel"></a>3.1&nbsp;消息通道
						</h2>
					</div>
				</div>
			</div>

			<p>
				在Spring Integration框架里，
				<code class="interfacename">Message</code>
				对象扮演着一个重要的角色，用于封装数据。而
				<code class="interfacename">MessageChannel</code>
				对象则用于解耦消息的生产者和消息的消息者。
			</p>

			<div class="section" title="3.1.1&nbsp;MessageChannel 接口">
				<div class="titlepage">
					<div>
						<div>
							<h3 class="title">
								<a name="channel-interfaces"></a>3.1.1&nbsp; MessageChannel
								接口
							</h3>
						</div>
					</div>
				</div>

				<p>
					Spring Integration的顶层
					<code class="interfacename">MessageChannel</code>
					接口定义如下：
				</p>
				<pre class="programlisting">
<span class="hl-keyword">public</span> <span class="hl-keyword">interface</span> MessageChannel {

    <span class="hl-keyword">boolean</span> send(Message message);

    <span class="hl-keyword">boolean</span> send(Message message, <span
						class="hl-keyword">long</span> timeout);
}</pre>
				<p></p>
				<p>
					发送消息时，如果发送成功，则返回值是 <span
						class="emphasis"><em>true</em></span>，如果发送失败，或者发送被中断了，则返回 <span class="emphasis"><em>false</em></span>.
				</p>

				<div class="section" title="PollableChannel">
					<div class="titlepage">
						<div>
							<div>
								<h4 class="title">
									<a name="channel-interfaces-pollablechannel"></a>PollableChannel
								</h4>
							</div>
						</div>
					</div>

					<p>
						我们在概述里提到过，消息通道可能采用消息缓冲，也可能不用。因此，有两个子接口用于
						定义缓冲型消息能道（轮询型），或非缓冲型消息通道（订阅型）。缓冲型消息通道
						<code class="interfacename">PollableChannel</code> 的定义如下：
						
					</p>
					<pre class="programlisting">
<span class="hl-keyword">public</span> <span class="hl-keyword">interface</span> PollableChannel <span
							class="hl-keyword">extends</span> MessageChannel {

    Message&lt;?&gt; receive();

    Message&lt;?&gt; receive(<span class="hl-keyword">long</span> timeout);

}</pre>
					<p></p>
					<p>
						和消息发送相似，如果接收超时或被中断，则返回 <span class="emphasis"><em>null</em></span>
					</p>
				</div>

				<div class="section" title="SubscribableChannel">
					<div class="titlepage">
						<div>
							<div>
								<h4 class="title">
									<a name="channel-interfaces-subscribablechannel"></a>SubscribableChannel
								</h4>
							</div>
						</div>
					</div>

					<p>
						
						<code class="interfacename">SubscribableChannel</code>
						接口会被非缓冲型通道所实现，这些通道直接向订阅了他们的
						<code class="interfacename">MessageHandler</code>发送消息。
						因此，他们不提供轮询消息接收，而是提供了管理订阅者的相关方法：
					</p>
					<pre class="programlisting">
<span class="hl-keyword">public</span> <span class="hl-keyword">interface</span> SubscribableChannel <span
							class="hl-keyword">extends</span> MessageChannel {

    <span class="hl-keyword">boolean</span> subscribe(MessageHandler handler);

    <span class="hl-keyword">boolean</span> unsubscribe(MessageHandler handler);

}</pre>
					<p></p>
				</div>
			</div>

			<div class="section"
				title="3.1.2&nbsp;消息通道的实现">
				<div class="titlepage">
					<div>
						<div>
							<h3 class="title">
								<a name="channel-implementations"></a>3.1.2&nbsp;消息通道的实现
							</h3>
						</div>
					</div>
				</div>

				<p>Spring Integration提供了几种不同的消息通道实现类。下面几小节将简单介绍这几个类。</p>
				<div class="section" title="PublishSubscribeChannel">
					<div class="titlepage">
						<div>
							<div>
								<h4 class="title">
									<a name="channel-implementations-publishsubscribechannel"></a>PublishSubscribeChannel
								</h4>
							</div>
						</div>
					</div>

					<p>						
						<code class="classname">PublishSubscribeChannel</code>
						把发向它的消息广播给它的所有订阅处理器。
						这个通道主要是用来发送 <span
							class="emphasis"><em>事件型消息Event Messages</em></span>，
						因为事件型消息的主要任务就是发出通告。与之相反的是<span class="emphasis"><em>文档型消息</em></span>，
						后者一般是在单个处理器里处理的。 需要注意的是，
						<code class="classname">PublishSubscribeChannel</code>
						只是用来发送消息。一旦它的
						<code class="methodname">send(Message)</code>
						方法被调用，它就会向它的订阅者广播。消费者不能向它轮询消息（它没有实现
						<code class="interfacename">PollableChannel</code>
						也没有
						<code class="methodname">receive()</code> 方法）。
						订阅者必须实现
						<code class="interfacename">MessageHandler</code>
						接口。在<code class="classname">PublishSubscribeChannel</code>
						广播的时候，订阅者的
						<code class="methodname">handleMessage(Message)</code>
						方法会依次被调用。
					</p>
				</div>
				<div class="section" title="QueueChannel">
					<div class="titlepage">
						<div>
							<div>
								<h4 class="title">
									<a name="channel-implementations-queuechannel"></a>QueueChannel
								</h4>
							</div>
						</div>
					</div>

					<p>
						
						<code class="classname">QueueChannel</code>
						包装了一个队列。和
						<code class="classname">PublishSubscribeChannel</code>
						不同，
						<code class="classname">QueueChannel</code>
						有着点到点的语义。换言之，即使该通道有多个消费者，也仅有一个消费者会接收
						到该通道里的消息。它有两个构造函数。无参数构造函数把队列容量设置为
						<code class="code">Integer.MAX_VALUE</code>。你也可以显式地
						设置某个队列容量值。
					</p>
					<pre class="programlisting">
<span class="hl-keyword">public</span> QueueChannel(<span
							class="hl-keyword">int</span> capacity)</pre>
					<p></p>
					<p>
						当通道队列还没有满的时候，消息会存放到它的内部队列中，而
						<code class="methodname">send()</code>方法会立即返回，即使没有接收者真的接收其消息。
						如果通道队列满了，发送者就会被阻塞，直到通道能有更多的空间。如果设置了超时时间，那么发送者
						会阻塞到有空间，或者超时。相似地，如果队列里有消息，那么接收者会马上返回。但如果通道为空，
						接收者会阻塞直到有消息到达为止，又者接收超时。
						无论是发送还是接收，都可以把超时时间设为0，让调用者马上返回。
						这里需要注意，对于无参数的<code class="methodname">send()</code>
						和
						<code class="methodname">receive()</code>，调用者都会无限期的阻塞。
					</p>
				</div>
				<div class="section" title="PriorityChannel">
					<div class="titlepage">
						<div>
							<div>
								<h4 class="title">
									<a name="channel-implementations-prioritychannel"></a>PriorityChannel
								</h4>
							</div>
						</div>
					</div>

					<p>						
						<code class="classname">QueueChannel</code>
						采用先进先出(FIFO)的服务方式，而
						<code class="classname">PriorityChannel</code>
						则允许消息在通道里按照优先级排队。缺省情况下，优先级由消息中的'
						<code class="literal">priority</code>
						' 头选择来指定。但你也可以设定自己的优先级算法，只需要实现一个比较
						算法
						<code class="classname">Comparator&lt;Message&lt;?&gt;&gt;</code>
						并配置到
						<code class="classname">PriorityChannel</code>
						的构造函数中去。
					</p>
				</div>
				<div class="section" title="RendezvousChannel">
					<div class="titlepage">
						<div>
							<div>
								<h4 class="title">
									<a name="channel-implementations-rendezvouschannel"></a>RendezvousChannel
								</h4>
							</div>
						</div>
					</div>

					<p>
						<code class="classname">RendezvousChannel</code>
						采用一种“不见不散”的方式来实现消息的传递。发送者会一直等待接收者来接收消息，
						其间会一直阻塞。如果接收者先启动，那么也会一直等待发送者发送其消息。
						其内部实现很接近
						<code class="classname">QueueChannel</code>
						，只是它使用
						<code class="classname">SynchronousQueue</code>
						(一种容量为 0 的
						<code class="interfacename">BlockingQueue</code>
						)。这种工作模式最适合同步发送者和接收者。假设发送者和接收者分别工作在不同的
						线程上，而异步的消息传递又不合适，也就是发送者必须等到接收者接收了消息才返回，
						那么就应该采用这种模式。换言之，如果使用
						<code class="classname">RendezvousChannel</code>
						发送者至少知道某个接收者把消息接收下来，而使用
						<code class="classname">QueueChannel</code>，
						消息有可能存入通道的队列里永远无人问津。
					</p>
					<div class="tip" title="Tip"
						style="margin-left: 0.5in; margin-right: 0.5in;">
						<table border="0" summary="Tip">
							<tr>
								<td rowspan="2" align="center" valign="top" width="25"><img
									alt="[Tip]" src="images/admon/tip.png"></td>
								<th align="left">Tip</th>
							</tr>
							<tr>
								<td align="left" valign="top">
									<p>
										应记住，基于队列的通道只是缺省采用内存来存放消息。如果你需要持久化消息，
										你可以给“queue”元素提供一个“message-store”属性，以指向一个持久化
										MessageStore实现。
										你也可以把本地通道换成一个有持久化broker支持的通道，比如说JMS通道，
										或采用通道适配器。后者让你可以选择任意一种JMS实现来支持消息持久化，
										这个做法将会在后面<a class="xref" href="jms.html"
											title="19.&nbsp;JMS Support">Chapter&nbsp;19, <i>JMS
												Support</i></a>中讨论到。然而，有时并不需要使用队列来缓冲消息，
										那么最简单的方法是用
										<code class="classname">DirectChannel</code>。我们马上就会讨论到
										<code class="classname">DirectChannel</code>。
									</p>
								</td>
							</tr>
						</table>
					</div>
					<p>						
						<code class="classname">RendezvousChannel</code>
						通道也可以用于实现请求-应用操作。发送者可以建立一个临时的、匿名的
						<code class="classname">RendezvousChannel</code>通道实例，
						然后用这个通道作为“replyChannel”头建立一个消息。
						发送消息后，发送者可以立即调用接收方法，以等待应用消息。调用接收方法时
						也可以指定一个超时值。这个方法和很多Spring Integration内部实现的请求-应答组件非常相似。						 
					</p>
				</div>
				<div class="section" title="DirectChannel">
					<div class="titlepage">
						<div>
							<div>
								<h4 class="title">
									<a name="channel-implementations-directchannel"></a>DirectChannel
								</h4>
							</div>
						</div>
					</div>

					<p>						
						<code class="classname">DirectChannel</code>
						有着点对点通道语义，然而除此以外，它和
						<code class="classname">PublishSubscribeChannel</code>
						非常相似。它实现了
						<code class="interfacename">SubscribableChannel</code>
						接口，而不是
						<code class="interfacename">PollableChannel</code>
						接口，所以它会直接分派消息到一个订阅者。
						然而，因为它是一个点对点的通道，所以和
						<code class="classname">PublishSubscribeChannel</code>
						不同，这个通道只会把一个消息发送到 <span class="emphasis"><em>单个</em></span>						
						<code class="classname">MessageHandler</code>
						。
					</p>
					<p>
						除了它的点对点语义外，<code class="classname">DirectChannel</code>
						的一个最重要特性是实现了“收发”两端的单线程处理。比如说，当一个处理器被订阅到
						<code class="classname">DirectChannel</code>
						，当一个消息被发送到这个通道时，发消操作会触发处理器的						
						<code class="methodname">handleMessage(Message)</code>
						方法，而且这个方法会<span class="emphasis"><em>直接运行在发送者的线程中</em></span>，
						也就是说，在send()方法返回之前被调用执行。
					</p>
					<p>
					这样做是为了在不同通道间实现事务支持的同时确保系统的抽象和松耦合。
					如果发送操作在事务内被调用，那么消息处理器的调用结果会影响到事务的最后结果，
					从而让事务决定到底是提交还是回滚。</p>
					<div class="note" title="Note"
						style="margin-left: 0.5in; margin-right: 0.5in;">
						<table border="0" summary="Note">
							<tr>
								<td rowspan="2" align="center" valign="top" width="25"><img
									alt="[Note]" src="images/admon/note.png"></td>
								<th align="left">Note</th>
							</tr>
							<tr>
								<td align="left" valign="top">由于<code
										class="classname">DirectChannel</code>是最简单的选择，而且没有
									带来任何额外的负担，系统既不需要安排调度或额外管理轮询器的线程。因此， <code
										class="classname">DirectChannel</code>是Spring Integration的
									缺省通道。一般而言，先定义应用程序所需要的通道，然后再去考虑它们是否需要缓冲处理，
									或者是否需要节流控制。如果需要这些特性，就可以考虑使用基于队列的<code
										class="interfacename">PollableChannels</code>。
									同样地，如果一个通道需要广播消息，它就应该是<code
										class="classname">PublishSubscribeChannel</code>而不是<code
										class="classname">DirectChannel</code>。接下来你将会看到这些都是可以配置的。
								</td>
							</tr>
						</table>
					</div>
					<p></p>
					<p>
						在Spring Integration的内部实现中，						
						<code class="classname">DirectChannel</code>会委派给消息分发器来
						调用注册到上面的消息处理器。这个消息分发器可以配置有负载均衡策略。
						如果有多个处理器同时注册到同一个<code class="classname">DirectChannel</code>
						上，那么负载均衡器会决定如何调用这些处理器。如果采用下面介绍到命名空间支持，
						那么缺省的策略将是“循环策略（round-robin）”，该策略就是循环地调用不同的处理器。
					</p>
					<div class="note" title="Note"
						style="margin-left: 0.5in; margin-right: 0.5in;">
						<table border="0" summary="Note">
							<tr>
								<td rowspan="2" align="center" valign="top" width="25"><img
									alt="[Note]" src="images/admon/note.png"></td>
								<th align="left">注意</th>
							</tr>
							<tr>
								<td align="left" valign="top">“循环策略”是目前唯一的官方策略。以后会有更多的策略加入。</td>
							</tr>
						</table>
					</div>
					<p></p>
					<p>
						负载均衡器还可以和 <span
							class="emphasis"><em>failover</em></span> 设置一同共同。如果
						"failover" 值为 true (缺省), 那么当某个处理器处理过程中发生异常，
						分派器就会向下一个处理器分派任务。处理器的执行顺利和它的注册顺序一致，
						除非设定可选的顺序值。
						</p>
						
					<p>If a certain situation requires that the dispatcher always
						try to invoke the first handler, then fallback in the same fixed
						order sequence every time an error occurs, no load-balancing
						strategy should be provided. In other words, the dispatcher still
						supports the failover boolean property even when no load-balancing
						is enabled. Without load-balancing, however, the invocation of
						handlers will always begin with the first according to their
						order. For example, this approach works well when there is a clear
						definition of primary, secondary, tertiary, and so on. When using
						the namespace support, the "order" attribute on any endpoint will
						determine that order.</p>
					<div class="note" title="Note"
						style="margin-left: 0.5in; margin-right: 0.5in;">
						<table border="0" summary="Note">
							<tr>
								<td rowspan="2" align="center" valign="top" width="25"><img
									alt="[Note]" src="images/admon/note.png"></td>
								<th align="left">Note</th>
							</tr>
							<tr>
								<td align="left" valign="top">Keep in mind that
									load-balancing and failover only apply when a channel has more
									than one subscribed Message Handler. When using the namespace
									support, this means that more than one endpoint shares the same
									channel reference in the "input-channel" attribute.</td>
							</tr>
						</table>
					</div>
				</div>
				<div class="section" title="ExecutorChannel">
					<div class="titlepage">
						<div>
							<div>
								<h4 class="title">
									<a name="executor-channel"></a>ExecutorChannel
								</h4>
							</div>
						</div>
					</div>

					<p>
						<code class="classname">ExecutorChannel</code>
						是一个点对点通道，它和						
						<code class="classname">DirectChannel</code>
						有着同样的分派器配置
						(负载均衡策略和故障切换设置)。关键的区别是，
						<code class="classname">ExecutorChannel</code>
						由
						<code class="interfacename">TaskExecutor</code>
						来执行分派工作。这意味着发送方法通常不会被阻塞。它同样意味着消息处理器的调用
						可能不在发送线程中。因此它<span
							class="emphasis"><em>在发送者和接收处理器之间支持事务</em></span>。
					</p>
					<div class="tip" title="Tip"
						style="margin-left: 0.5in; margin-right: 0.5in;">
						<table border="0" summary="Tip">
							<tr>
								<td rowspan="2" align="center" valign="top" width="25"><img
									alt="[Tip]" src="images/admon/tip.png"></td>
								<th align="left">Tip</th>
							</tr>
							<tr>
								<td align="left" valign="top">需要知道的是，某种情况下，发送还是有可能被阻塞的。
								比如TaskExecutor配置了rejection-policy，并设定阈值
								（比如<code class="code">ThreadPoolExecutor.CallerRunsPolicy</code>），
								当执行器的线程池已满时，发送任务会直接在执行在发送者自身的线程里。这些情况并不可
								预先知道，从而也不能用于实现事务支持。
								</td>
							</tr>
						</table>
					</div>
					<p></p>
				</div>
				<div class="section" title="Scoped Channel">
					<div class="titlepage">
						<div>
							<div>
								<h4 class="title">
									<a name="channel-implementations-threadlocalchannel"></a>Scoped
									Channel
								</h4>
							</div>
						</div>
					</div>

					<p>
						Spring Integration 1.0提供了
						<code class="classname">ThreadLocalChannel</code>的通道实现，但从2.0开始，
						这种通道被移除。现在有更通用的方法来实现这种需求，就是向通道中加入“scope”属性。
						“scope”的值可以是任何上下文支持的名称。比如在Web环境中，有几种scope被支持，
						用户还可以定制自己的scope。这里有一个例子是实现ThreadLocal scope的，该例还包括了
						scope的注册处理：
					</p>
					<pre class="programlisting"> <span class="hl-tag">&lt;int:channel</span> <span
							class="hl-attribute">id</span>=<span class="hl-value">"threadScopedChannel"</span> <span
							class="hl-attribute">scope</span>=<span class="hl-value">"thread"</span><span
							class="hl-tag">&gt;</span>
     <span class="hl-tag">&lt;int:queue /&gt;</span>
 <span class="hl-tag">&lt;/int:channel&gt;</span>
	
 <span class="hl-tag">&lt;bean</span> <span class="hl-attribute">class</span>=<span
							class="hl-value">"org.springframework.beans.factory.config.CustomScopeConfigurer"</span><span
							class="hl-tag">&gt;</span>
    <span class="hl-tag">&lt;property</span> <span class="hl-attribute">name</span>=<span
							class="hl-value">"scopes"</span><span class="hl-tag">&gt;</span>
         <span class="hl-tag">&lt;map&gt;</span>
             <span class="hl-tag">&lt;entry</span> <span
							class="hl-attribute">key</span>=<span class="hl-value">"thread"</span> <span
							class="hl-attribute">value</span>=<span class="hl-value">"org.springframework.context.support.SimpleThreadScope"</span><span
							class="hl-tag"> /&gt;</span>
         <span class="hl-tag">&lt;/map&gt;</span>
     <span class="hl-tag">&lt;/property&gt;</span>
 <span class="hl-tag">&lt;/bean&gt;</span>
</pre>
					<p>
						The channel above also delegates to a queue internally, but the
						channel is bound to the current thread, so the contents of the
						queue are as well. That way the thread that sends to the channel
						will later be able to receive those same Messages, but no other
						thread would be able to access them. While thread-scoped channels
						are rarely needed, they can be useful in situations where
						<code class="classname">DirectChannels</code>
						are being used to enforce a single thread of operation but any
						reply Messages should be sent to a "terminal" channel. If that
						terminal channel is thread-scoped, the original sending thread can
						collect its replies from it.
					</p>
					<p>Now, since any channel can be scoped, you can define your
						own scopes in addition to Thread Local.</p>
				</div>
			</div>

			<div class="section" title="3.1.3&nbsp;通道拦截器">
				<div class="titlepage">
					<div>
						<div>
							<h3 class="title">
								<a name="channel-interceptors"></a>3.1.3&nbsp;通道拦截器
							</h3>
						</div>
					</div>
				</div>

				<p>
					消息处理架构的一个好处是它提供了消息在系统中传送时的公共行为模式，以及在传送过程中
					获取有意义的信息。这些都采用一种非入侵的方式来实现。
					由于
					<code class="interfacename">消息</code>
					都是发向或收自
					<code class="interfacename">消息通道</code>的，
					这些通道也就可以让拦截器截获消息发送和接收操作。
					<code class="interfacename">ChannelInterceptor</code>
					策略接口提供了实现这些操作的各种方法：
				</p>
				<pre class="programlisting">
<span class="hl-keyword">public</span> <span class="hl-keyword">interface</span> ChannelInterceptor {

    Message&lt;?&gt; preSend(Message&lt;?&gt; message, MessageChannel channel);

    <span class="hl-keyword">void</span> postSend(Message&lt;?&gt; message, MessageChannel channel, <span
						class="hl-keyword">boolean</span> sent);

    <span class="hl-keyword">boolean</span> preReceive(MessageChannel channel);

    Message&lt;?&gt; postReceive(Message&lt;?&gt; message, MessageChannel channel);
}</pre>
				<p>一旦实现了这个接口，向通道注册一个拦截器就只需要调用：</p>
				<pre class="programlisting">channel.addInterceptor(someChannelInterceptor);</pre>
				<p>
					返回Message实例的方法可以用来实现消息变换。你也可以返回“null”来终止进一步处理。
					当然，你也可以让拦截器抛出异常。另外，
					<code class="methodname">preReceive</code>
					方法可以返回
					<code class="literal">false</code>，以阻止接收操作的执行。
				</p>
				<div class="note" title="Note"
					style="margin-left: 0.5in; margin-right: 0.5in;">
					<table border="0" summary="Note">
						<tr>
							<td rowspan="2" align="center" valign="top" width="25"><img
								alt="[Note]" src="images/admon/note.png"></td>
							<th align="left">Note</th>
						</tr>
						<tr>
							<td align="left" valign="top">Keep in mind that <code
									class="methodname">receive()</code> calls are only relevant for
								<code class="interfacename">PollableChannels</code>. In fact the
								<code class="interfacename">SubscribableChannel</code> interface
								does not even define a <code class="methodname">receive()</code>
								method. The reason for this is that when a Message is sent to a
								<code class="interfacename">SubscribableChannel</code> it will
								be sent directly to one or more subscribers depending on the
								type of channel (e.g. a PublishSubscribeChannel sends to all of
								its subscribers). Therefore, the <code class="methodname">preReceive(..)</code>
								and <code class="methodname">postReceive(..)</code> interceptor
								methods are only invoked when the interceptor is applied to a <code
									class="interfacename">PollableChannel</code>.
							</td>
						</tr>
					</table>
				</div>
				<p>
					Spring Integration还提供了<a
						class="ulink" href="http://eaipatterns.com/WireTap.html"
						target="_top">截听</a>模式。它是一个简单的拦截器，把消息转发到另一个通道而不改变现有的消息流。
					截听模式在调式或监控时会很有用。在<a class="xref"
						href="messaging-channels-section.html#channel-wiretap"
						title="Wire Tap">“截听”一节中</a>有一个相关的例子。
				</p>
				<p>
					Because it is rarely necessary to implement all of the interceptor
					methods, a
					<code class="classname">ChannelInterceptorAdapter</code>
					class is also available for sub-classing. It provides no-op methods
					(the
					<code class="literal">void</code>
					method is empty, the
					<code class="classname">Message</code>
					returning methods return the Message as-is, and the
					<code class="literal">boolean</code>
					method returns
					<code class="literal">true</code>
					). Therefore, it is often easiest to extend that class and just
					implement the method(s) that you need as in the following example.
				</p>
				<pre class="programlisting">
<span class="hl-keyword">public</span> <span class="hl-keyword">class</span> CountingChannelInterceptor <span
						class="hl-keyword">extends</span> ChannelInterceptorAdapter {

    <span class="hl-keyword">private</span> <span class="hl-keyword">final</span> AtomicInteger sendCount = <span
						class="hl-keyword">new</span> AtomicInteger();

    <i><span class="hl-annotation" style="color: gray">@Override</span></i>
    <span class="hl-keyword">public</span> Message&lt;?&gt; preSend(Message&lt;?&gt; message, MessageChannel channel) {
        sendCount.incrementAndGet();
        <span class="hl-keyword">return</span> message;
    }
}</pre>
				<p></p>
				<div class="tip" title="Tip"
					style="margin-left: 0.5in; margin-right: 0.5in;">
					<table border="0" summary="Tip">
						<tr>
							<td rowspan="2" align="center" valign="top" width="25"><img
								alt="[Tip]" src="images/admon/tip.png"></td>
							<th align="left">Tip</th>
						</tr>
						<tr>
							<td align="left" valign="top">The order of invocation for
								the interceptor methods depends on the type of channel. As
								described above, the queue-based channels are the only ones
								where the receive method is intercepted in the first place.
								Additionally, the relationship between send and receive
								interception depends on the timing of separate sender and
								receiver threads. For example, if a receiver is already blocked
								while waiting for a message the order could be: preSend,
								preReceive, postReceive, postSend. However, if a receiver polls
								after the sender has placed a message on the channel and already
								returned, the order would be: preSend, postSend,
								(some-time-elapses) preReceive, postReceive. The time that
								elapses in such a case depends on a number of factors and is
								therefore generally unpredictable (in fact, the receive may
								never happen!). Obviously, the type of queue also plays a role
								(e.g. rendezvous vs. priority). The bottom line is that you
								cannot rely on the order beyond the fact that preSend will
								precede postSend and preReceive will precede postReceive.</td>
						</tr>
					</table>
				</div>
				<p></p>
			</div>

			<div class="section" title="3.1.4&nbsp;MessagingTemplate">
				<div class="titlepage">
					<div>
						<div>
							<h3 class="title">
								<a name="channel-template"></a>3.1.4&nbsp;MessagingTemplate
							</h3>
						</div>
					</div>
				</div>

				<p>
					As you will see when the endpoints and their various configuration
					options are introduced, Spring Integration provides a foundation
					for messaging components that enables non-invasive invocation of
					your application code <span class="emphasis"><em>from
							the messaging system</em></span>. However, sometimes it is necessary to
					invoke the messaging system <span class="emphasis"><em>from
							your application code</em></span>. For convenience when implementing such
					use-cases, Spring Integration provides a
					<code class="classname">MessagingTemplate</code>
					that supports a variety of operations across the Message Channels,
					including request/reply scenarios. For example, it is possible to
					send a request and wait for a reply.
				</p>
				<pre class="programlisting">MessagingTemplate template = <span
						class="hl-keyword">new</span> MessagingTemplate();

Message reply = template.sendAndReceive(someChannel, <span
						class="hl-keyword">new</span> GenericMessage(<span
						class="hl-string">"test"</span>));</pre>
				<p></p>
				<p>In that example, a temporary anonymous channel would be
					created internally by the template. The 'sendTimeout' and
					'receiveTimeout' properties may also be set on the template, and
					other exchange types are also supported.</p>
				<pre class="programlisting">
<span class="hl-keyword">public</span> <span class="hl-keyword">boolean</span> send(<span
						class="hl-keyword">final</span> MessageChannel channel, <span
						class="hl-keyword">final</span> Message&lt;?&gt; message) { ... }

<span class="hl-keyword">public</span> Message&lt;?&gt; sendAndReceive(<span
						class="hl-keyword">final</span> MessageChannel channel, <span
						class="hl-keyword">final</span> Message&lt;?&gt; request) { .. }

<span class="hl-keyword">public</span> Message&lt;?&gt; receive(<span
						class="hl-keyword">final</span> PollableChannel&lt;?&gt; channel) { ... }</pre>
				<p></p>
				<div class="note" title="Note"
					style="margin-left: 0.5in; margin-right: 0.5in;">
					<table border="0" summary="Note">
						<tr>
							<td rowspan="2" align="center" valign="top" width="25"><img
								alt="[Note]" src="images/admon/note.png"></td>
							<th align="left">Note</th>
						</tr>
						<tr>
							<td align="left" valign="top">
								<p>
									A less invasive approach that allows you to invoke simple
									interfaces with payload and/or header values instead of Message
									instances is described in <a class="xref"
										href="messaging-endpoints-chapter.html#gateway-proxy"
										title="7.2.1&nbsp;Enter the GatewayProxyFactoryBean">Section&nbsp;7.2.1,
										&#8220;Enter the GatewayProxyFactoryBean&#8221;</a>.
								</p>
							</td>
						</tr>
					</table>
				</div>
			</div>

			<div class="section" title="3.1.5&nbsp;配置消息通道">
				<div class="titlepage">
					<div>
						<div>
							<h3 class="title">
								<a name="channel-configuration"></a>3.1.5&nbsp;配置消息通道
							</h3>
						</div>
					</div>
				</div>

				<p>你可以用&lt;channel/&gt;元素来建立一个消息通道实际。</p>
				<pre class="programlisting"><span class="hl-tag">&lt;int:channel</span> <span
						class="hl-attribute">id</span>=<span class="hl-value">"exampleChannel"</span><span
						class="hl-tag">/&gt;</span>
				</pre>
				<p></p>
				<p>
					缺省的通道类型是<span class="emphasis"><em>点对点通道</em></span>。如果想建立一个<span class="emphasis"><em>发送订阅通道</em></span>
					你可以使用&lt;publish-subscribe-channel/&gt;元素。
				</p>
				<pre class="programlisting"><span class="hl-tag">&lt;int:publish-subscribe-channel</span> <span
						class="hl-attribute">id</span>=<span class="hl-value">"exampleChannel"</span><span
						class="hl-tag">/&gt;</span>
				</pre>
				<p></p>
				<p>
					如果不提供子元素而仅使用&lt;channel/&gt; 来建立通道，它将会建立一个
					<code class="classname">DirectChannel</code>实例。
					(一个<code class="interfacename">SubscribableChannel</code>
					).
				</p>
				<p>
					你也可以提供若干&lt;queue/&gt;子元素来建立任何轮询型通道，也就是那些在<a class="xref"
						href="messaging-channels-section.html#channel-implementations"
						title="3.1.2&nbsp;Message Channel Implementations">Section&nbsp;3.1.2,
						&#8220;Message Channel Implementations&#8221;</a>)介绍到的通道类型。下面会逐个介绍这些通道建立的例子。
				</p>
				<div class="section" title="DirectChannel 配置">
					<div class="titlepage">
						<div>
							<div>
								<h4 class="title">
									<a name="channel-configuration-directchannel"></a>DirectChannel
									配置
								</h4>
							</div>
						</div>
					</div>

					<p>
						上面已经说到
						<code class="classname">DirectChannel</code>
						是缺省通道。
					</p>
					<pre class="programlisting"><span class="hl-tag">&lt;int:channel</span> <span
							class="hl-attribute">id</span>=<span class="hl-value">"directChannel"</span><span
							class="hl-tag">/&gt;</span>
					</pre>
					<p></p>
					<p>
						缺省的情况下，一个通道会带一个<span class="emphasis"><em>循环型</em></span>负载均衡器，
						它同时还启动了故障切换（详情请参考<a class="xref"
							href="messaging-channels-section.html#channel-implementations-directchannel"
							title="DirectChannel">
							&#8220;DirectChannel&#8221;一节</a>)。要禁用其中之一还全部，需要设置一个&lt;dispatcher/&gt;
						子元素并配置相关属性：
					</p>
					<pre class="programlisting"><span class="hl-tag">&lt;int:channel</span> <span
							class="hl-attribute">id</span>=<span class="hl-value">"failFastChannel"</span><span
							class="hl-tag">&gt;</span>
    <span class="hl-tag">&lt;int:dispatcher</span> <span
							class="hl-attribute">failover</span>=<span class="hl-value">"false"</span><span
							class="hl-tag">/&gt;</span>
<span class="hl-tag">&lt;/channel&gt;</span>

<span class="hl-tag">&lt;int:channel</span> <span class="hl-attribute">id</span>=<span
							class="hl-value">"channelWithFixedOrderSequenceFailover"</span><span
							class="hl-tag">&gt;</span>
    <span class="hl-tag">&lt;int:dispatcher</span> <span
							class="hl-attribute">load-balancer</span>=<span class="hl-value">"none"</span><span
							class="hl-tag">/&gt;</span>
<span class="hl-tag">&lt;/int:channel&gt;</span>
</pre>
					<p></p>
				</div>

				<div class="section" title="数据类型通道及配置">
					<div class="titlepage">
						<div>
							<div>
								<h4 class="title">
									<a name="channel-datatype-channel"></a>数据类型通道及配置
								</h4>
							</div>
						</div>
					</div>

					<p>
						有时消息的消费者只能处理某种指定的载荷类型，这时你就需要确保输入消息的载荷类型为指定的那些类型了。
						当然，你可能马上想到消息过滤器。然而所有的消息过滤器都只是过滤那些不想要的的消息。另一种可行的方案是
						使用基于内容的路由器，让路由器把不合要求的消息转到一些特别的转换器上进行转换，以获得想要的数据类型。
						这当然也是可以的，但一种更简单的实现方法是使用 <a class="ulink"
							href="http://www.eaipatterns.com/DatatypeChannel.html"
							target="_top">数据类型通道模式</a>。你可以为每一种载荷类型指定一个独立的数据类型通道。
					</p>
					<p>
						只要你向通道的<code class="literal">datatype</code>属性指定目标载荷数据类型的完整类名，就可以让该通道只接受该类型的消息:
					</p>
					<pre class="programlisting"><span class="hl-tag">&lt;int:channel</span> <span
							class="hl-attribute">id</span>=<span class="hl-value">"numberChannel"</span> <span
							class="hl-attribute">datatype</span>=<span class="hl-value">"java.lang.Number"</span><span
							class="hl-tag">/&gt;</span>
					</pre>
					<p></p>
					<p>
					注意类型校验是通过判断输入载荷是否能 <span
							class="emphasis"><em>赋值于</em></span>通道的数据类型。
					对上面的例子来说，“numberChannel”可以接受的载荷包括：
						<code class="classname">java.lang.Integer</code>
						或
						<code class="classname">java.lang.Double</code>
						。你可以指定多个类型，不同类之间用逗号分开：
					</p>
					<pre class="programlisting"><span class="hl-tag">&lt;int:channel</span> <span
							class="hl-attribute">id</span>=<span class="hl-value">"stringOrNumberChannel"</span> <span
							class="hl-attribute">datatype</span>=<span class="hl-value">"java.lang.String,java.lang.Number"</span><span
							class="hl-tag">/&gt;</span>
					</pre>
					<p></p>
					<p>
					既然“numberChannel”只可以接受载何为
						<code class="classname">java.lang.Number</code>
					的消息，一旦有不符合要求的消息发送过来，会出现什么情况呢？这个要看情况。如果你没有设定一个名为“integrationConversionService”
					的<a
							class="ulink"
							href="http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/validation.html#core-convert-ConversionService-API"
							target="_top">转换服务</a>组件，那么会立即抛出一个异常。但如果你有这样一个组件，这个实例就会尝试把载荷转换过来。
					</p>
					<p>
					你甚至可以注册自定义的转换器。比如你向上面定义的“numberChannel”发送一个字符串载荷。</p>
					<pre class="programlisting">MessageChannel inChannel = context.getBean(<span
							class="hl-string">"numberChannel"</span>, MessageChannel.<span
							class="hl-keyword">class</span>);
inChannel.send(<span class="hl-keyword">new</span> GenericMessage&lt;String&gt;(<span
							class="hl-string">"5"</span>));</pre>
					<p></p>
					<p>这本来是合法的操作。然而因为我们使用了数据类型通道，上面的操作就会产生一个异常：</p>
					<pre class="programlisting">Exception in thread <span
							class="hl-string">"main"</span> org.springframework.integration.MessageDeliveryException: 
Channel <span class="hl-string">'numberChannel'</span> 
expected one of the following datataypes [<span class="hl-keyword">class</span> java.lang.Number], 
but received [<span class="hl-keyword">class</span> java.lang.String]
&#8230;</pre>
					<p></p>
					<p>
					我们都知道不应该发送一个字符串，而应该发送一个数值型消息。因此我们需要一个把字符串转换成
					数值型数据的转换器：</p>
					<pre class="programlisting"><span class="hl-keyword">public</span> <span class="hl-keyword">static</span> <span
							class="hl-keyword">class</span> StringToIntegerConverter <span
							class="hl-keyword">implements</span> Converter&lt;String, Integer&gt; {
	<span class="hl-keyword">public</span> Integer convert(String source) {
		<span class="hl-keyword">return</span> Integer.parseInt(source);
	}	
}</pre>
					<p></p>
					<p>然后把这个转换器注册到集成转换服务上：</p>
					<pre class="programlisting">&lt;<span class="hl-keyword">int</span>:converter ref=<span
							class="hl-string">"strToInt"</span>/&gt;
	
&lt;bean id=<span class="hl-string">"strToInt"</span> <span
							class="hl-keyword">class</span>=<span class="hl-string">"org.springframework.integration.util.Demo.StringToIntegerConverter"</span>/&gt;</pre>
					<p></p>
					<p>
					当“converter”元素被解析的时候，如果之前没有“integrationConversionService”组件，它就会生成这样一个组件。
					有了这个转换器，发送操作就可以顺利进行，数据类型通道就会使用这个转换器把字符串载荷转换成整数值。</p>
				</div>

				<div class="section" title="QueueChannel 配置">
					<div class="titlepage">
						<div>
							<div>
								<h4 class="title">
									<a name="channel-configuration-queuechannel"></a>QueueChannel
									配置
								</h4>
							</div>
						</div>
					</div>

					<p>
						要建立一个
						<code class="classname">QueueChannel</code>
						，可以使用一个 &lt;queue/&gt; 子元素。你还可以设定队列的容量：
					</p>
					<pre class="programlisting"><span class="hl-tag">&lt;int:channel</span> <span
							class="hl-attribute">id</span>=<span class="hl-value">"queueChannel"</span><span
							class="hl-tag">&gt;</span>
    <span class="hl-tag">&lt;queue</span> <span class="hl-attribute">capacity</span>=<span
							class="hl-value">"25"</span><span class="hl-tag">/&gt;</span>
<span class="hl-tag">&lt;/int:channel&gt;</span>
					</pre>
					<p></p>
					<div class="note" title="Note"
						style="margin-left: 0.5in; margin-right: 0.5in;">
						<table border="0" summary="Note">
							<tr>
								<td rowspan="2" align="center" valign="top" width="25"><img
									alt="[Note]" src="images/admon/note.png"></td>
								<th align="left">注意</th>
							</tr>
							<tr>
								<td align="left" valign="top">如果你不设定一个“capacity”属性值，那么队列将会是无限长的，
								这就有可能导致内存溢出问题。所以非常建议你指定队列的大小。</td>
							</tr>
						</table>
					</div>
					<p></p>

					<p>
						<span class="emphasis"><em>持久化QueueChannel配置</em></span>
					</p>

					<p>
						在缺省情况下，<code class="classname">QueueChannel</code>把消息缓冲在内存里，
						一旦系统出错，消息有可能会丢失。为了减少这种风险，我们可以让
						<code class="classname">QueueChannel</code>
						建立在某种
						<code class="classname">MessageGroupStore</code>
						策略接口上。要了解更详细的关于
						<code class="classname">MessageGroupStore</code>
						和
						<code class="classname">MessageStore</code>
						的信息，请查看
						<a class="xref"
							href="system-management-chapter.html#message-store"
							title="8.3&nbsp;Message Store">Section&nbsp;8.3,
							&#8220;Message Store&#8221;</a>。
					</p>
					<p>
						当
						<code class="classname">QueueChannel</code>
						接收到一个消息的时候，它把消息存入消息存贮库，当消息被轮询到的时候，
						它将会从存贮库里移除。
					</p>
					<p>
						缺省情况下，
						<code class="classname">QueueChannel</code>
						仅把消息存放在内存队列中，因而有机会出现上面提到的消息丢失的问题。Spring Integration
						提供了						
						<code class="classname">JdbcMessageStore</code>
						来让
						<code class="classname">QueueChannel</code>
						把消息存入关系数据库中（RDBMS）。
					</p>
					<p>
						你可以为任一
						<code class="classname">QueueChannel</code>
						配置消息存贮库，其方法是给通道设置一个
						<code class="code">message-store</code>
						属性，就如下例所示：
					</p>
					<pre class="programlisting"><span class="hl-tag">&lt;int:channel</span> <span
							class="hl-attribute">id</span>=<span class="hl-value">"dbBackedChannel"</span><span
							class="hl-tag">&gt;</span>
    <span class="hl-tag">&lt;int:queue</span> <span class="hl-attribute">message-store</span>=<span
							class="hl-value">"messageStore"</span><span class="hl-tag">&gt;</span>
<span class="hl-tag">&lt;int:channel</span> <span class="hl-attribute">id</span>=<span
							class="hl-value">"myChannel"</span><span class="hl-tag">&gt;</span>

<span class="hl-tag">&lt;int-jdbc:message-store</span> <span
							class="hl-attribute">id</span>=<span class="hl-value">"messageStore"</span> <span
							class="hl-attribute">data-source</span>=<span class="hl-value">"someDataSource"</span><span
							class="hl-tag">/&gt;</span>
					</pre>
					<p>
						上例同时说明Spring Integration JDBC模块提供了对
						<code class="classname">JdbcMessageStore</code>
						的命名空间的支持。你只需要注入一个
						<code class="classname">javax.sql.DataSource</code>
						实例即可。Spring Integration JDBC模块同时还提供了多数流行数据库的DDL模式。
						这些模式就存放在<span
							class="emphasis"><em>org.springframework.integration.jdbc</em></span>
						包中（spring-integration-jdbc）。
					</p>
					<div class="important" title="重要信息"
						style="margin-left: 0.5in; margin-right: 0.5in;">
						<table border="0" summary="Important">
							<tr>
								<td rowspan="2" align="center" valign="top" width="25"><img
									alt="[Important]" src="images/admon/important.png"></td>
								<th align="left">重要信息</th>
							</tr>
							<tr>
								<td align="left" valign="top">One important feature is that
									with any transactional persistent store (e.g.,
									JdbcMessageStore), as long as the poller has a transaction
									configured, a Message removed from the store will only be
									permanently removed if the transaction completes successfully,
									otherwise the transaction will roll back and the Message will
									not be lost.</td>
							</tr>
						</table>
					</div>
					<p>Many other implementations of the Message Store will be
						available as the growing number of Spring projects related to
						"NoSQL" data stores provide the underlying support. Of course, you
						can always provide your own implementation of the
						MessageGroupStore interface if you cannot find one that meets your
						particular needs.</p>
				</div>

				<div class="section" title="PublishSubscribeChannel Configuration">
					<div class="titlepage">
						<div>
							<div>
								<h4 class="title">
									<a name="channel-configuration-pubsubchannel"></a>PublishSubscribeChannel
									Configuration
								</h4>
							</div>
						</div>
					</div>

					<p>
						To create a
						<code class="classname">PublishSubscribeChannel</code>
						, use the &lt;publish-subscribe-channel/&gt; element. When using
						this element, you can also specify the
						<code class="code">task-executor</code>
						used for publishing Messages (if none is specified it simply
						publishes in the sender's thread):
					</p>
					<pre class="programlisting">
						<span class="hl-tag">&lt;int:publish-subscribe-channel</span> <span
							class="hl-attribute">id</span>=<span class="hl-value">"pubsubChannel"</span> <span
							class="hl-attribute">task-executor</span>=<span class="hl-value">"someExecutor"</span><span
							class="hl-tag">/&gt;</span>
					</pre>
					<p>
						If you are providing a <span class="emphasis"><em>Resequencer</em></span>
						or <span class="emphasis"><em>Aggregator</em></span> downstream
						from a
						<code class="classname">PublishSubscribeChannel</code>
						, then you can set the 'apply-sequence' property on the channel to
						<code class="code">true</code>
						. That will indicate that the channel should set the sequence-size
						and sequence-number Message headers as well as the correlation id
						prior to passing the Messages along. For example, if there are 5
						subscribers, the sequence-size would be set to 5, and the Messages
						would have sequence-number header values ranging from 1 to 5.
					</p>
					<pre class="programlisting">
						<span class="hl-tag">&lt;int:publish-subscribe-channel</span> <span
							class="hl-attribute">id</span>=<span class="hl-value">"pubsubChannel"</span> <span
							class="hl-attribute">apply-sequence</span>=<span class="hl-value">"true"</span><span
							class="hl-tag">/&gt;</span>
					</pre>
					<p></p>
					<div class="note" title="Note"
						style="margin-left: 0.5in; margin-right: 0.5in;">
						<table border="0" summary="Note">
							<tr>
								<td rowspan="2" align="center" valign="top" width="25"><img
									alt="[Note]" src="images/admon/note.png"></td>
								<th align="left">Note</th>
							</tr>
							<tr>
								<td align="left" valign="top">The <code class="code">apply-sequence</code>
									value is <code class="code">false</code> by default so that a
									Publish Subscribe Channel can send the exact same Message
									instances to multiple outbound channels. Since Spring
									Integration enforces immutability of the payload and header
									references, the channel creates new Message instances with the
									same payload reference but different header values when the
									flag is set to <code class="code">true</code>.
								</td>
							</tr>
						</table>
					</div>
					<p></p>
				</div>
				<div class="section" title="ExecutorChannel">
					<div class="titlepage">
						<div>
							<div>
								<h4 class="title">
									<a name="channel-configuration-executorchannel"></a>ExecutorChannel
								</h4>
							</div>
						</div>
					</div>

					<p>
						To create an
						<code class="classname">ExecutorChannel</code>
						, add the &lt;dispatcher&gt; sub-element along with a
						<code class="code">task-executor</code>
						attribute. Its value can reference any
						<code class="interfacename">TaskExecutor</code>
						within the context. For example, this enables configuration of a
						thread-pool for dispatching messages to subscribed handlers. As
						mentioned above, this does break the "single-threaded" execution
						context between sender and receiver so that any active transaction
						context will not be shared by the invocation of the handler (i.e.
						the handler may throw an Exception, but the send invocation has
						already returned successfully).
					</p>
					<pre class="programlisting">
						<span class="hl-tag">&lt;int:channel</span> <span
							class="hl-attribute">id</span>=<span class="hl-value">"executorChannel"</span><span
							class="hl-tag">&gt;</span>
    <span class="hl-tag">&lt;int:dispatcher</span> <span
							class="hl-attribute">task-executor</span>=<span class="hl-value">"someExecutor"</span><span
							class="hl-tag">/&gt;</span>
<span class="hl-tag">&lt;/int:channel&gt;</span>
					</pre>
					<p></p>
					<div class="note" title="Note"
						style="margin-left: 0.5in; margin-right: 0.5in;">
						<table border="0" summary="Note">
							<tr>
								<td rowspan="2" align="center" valign="top" width="25"><img
									alt="[Note]" src="images/admon/note.png"></td>
								<th align="left">Note</th>
							</tr>
							<tr>
								<td align="left" valign="top">The <code class="code">load-balancer</code>
									and <code class="code">failover</code> options are also both
									available on the &lt;dispatcher/&gt; sub-element as described
									above in <a class="xref"
									href="messaging-channels-section.html#channel-configuration-directchannel"
									title="DirectChannel Configuration">the section called
										&#8220;DirectChannel Configuration&#8221;</a>. The same defaults
									apply as well. So, the channel will have a round-robin
									load-balancing strategy with failover enabled unless explicit
									configuration is provided for one or both of those attributes.
									<pre class="programlisting">
										<span class="hl-tag">&lt;int:channel</span> <span
											class="hl-attribute">id</span>=<span class="hl-value">"executorChannelWithoutFailover"</span><span
											class="hl-tag">&gt;</span>
    <span class="hl-tag">&lt;int:dispatcher</span> <span
											class="hl-attribute">task-executor</span>=<span
											class="hl-value">"someExecutor"</span> <span
											class="hl-attribute">failover</span>=<span class="hl-value">"false"</span><span
											class="hl-tag">/&gt;</span>
<span class="hl-tag">&lt;/int:channel&gt;</span>
									</pre>
								</td>
							</tr>
						</table>
					</div>
				</div>
				<div class="section" title="PriorityChannel Configuration">
					<div class="titlepage">
						<div>
							<div>
								<h4 class="title">
									<a name="channel-configuration-prioritychannel"></a>PriorityChannel
									Configuration
								</h4>
							</div>
						</div>
					</div>

					<p>
						To create a
						<code class="classname">PriorityChannel</code>
						, use the &lt;priority-queue/&gt; sub-element:
					</p>
					<pre class="programlisting">
						<span class="hl-tag">&lt;int:channel</span> <span
							class="hl-attribute">id</span>=<span class="hl-value">"priorityChannel"</span><span
							class="hl-tag">&gt;</span>
    <span class="hl-tag">&lt;int:priority-queue</span> <span
							class="hl-attribute">capacity</span>=<span class="hl-value">"20"</span><span
							class="hl-tag">/&gt;</span>
<span class="hl-tag">&lt;/int:channel&gt;</span>
					</pre>
					<p>
						By default, the channel will consult the
						<code class="code">priority</code>
						header of the message. However, a custom
						<code class="interfacename">Comparator</code>
						reference may be provided instead. Also, note that the
						<code class="classname">PriorityChannel</code>
						(like the other types) does support the
						<code class="code">datatype</code>
						attribute. As with the QueueChannel, it also supports a
						<code class="code">capacity</code>
						attribute. The following example demonstrates all of these:
					</p>
					<pre class="programlisting">
						<span class="hl-tag">&lt;int:channel</span> <span
							class="hl-attribute">id</span>=<span class="hl-value">"priorityChannel"</span> <span
							class="hl-attribute">datatype</span>=<span class="hl-value">"example.Widget"</span><span
							class="hl-tag">&gt;</span>
    <span class="hl-tag">&lt;int:priority-queue</span> <span
							class="hl-attribute">comparator</span>=<span class="hl-value">"widgetComparator"</span>
                    <span class="hl-attribute">capacity</span>=<span
							class="hl-value">"10"</span><span class="hl-tag">/&gt;</span>
<span class="hl-tag">&lt;/int:channel&gt;</span>
</pre>
					<p></p>
				</div>
				<div class="section" title="RendezvousChannel Configuration">
					<div class="titlepage">
						<div>
							<div>
								<h4 class="title">
									<a name="channel-configuration-rendezvouschannel"></a>RendezvousChannel
									Configuration
								</h4>
							</div>
						</div>
					</div>

					<p>
						A
						<code class="classname">RendezvousChannel</code>
						is created when the queue sub-element is a
						&lt;rendezvous-queue&gt;. It does not provide any additional
						configuration options to those described above, and its queue does
						not accept any capacity value since it is a 0-capacity direct
						handoff queue.
					</p>
					<pre class="programlisting">
						<span class="hl-tag">&lt;int:channel</span> <span
							class="hl-attribute">id</span>=<span class="hl-value">"rendezvousChannel"</span><span
							class="hl-tag">/&gt;</span>
    <span class="hl-tag">&lt;int:rendezvous-queue/&gt;</span>
<span class="hl-tag">&lt;/int:channel&gt;</span>
</pre>
					<p></p>
				</div>
				<div class="section" title="Scoped Channel Configuration">
					<div class="titlepage">
						<div>
							<div>
								<h4 class="title">
									<a name="channel-configuration-threadlocalchannel"></a>Scoped
									Channel Configuration
								</h4>
							</div>
						</div>
					</div>

					<p>Any channel can be configured with a "scope" attribute.</p>
					<pre class="programlisting">
						<span class="hl-tag">&lt;int:channel</span> <span
							class="hl-attribute">id</span>=<span class="hl-value">"threadLocalChannel"</span> <span
							class="hl-attribute">scope</span>=<span class="hl-value">"thread"</span><span
							class="hl-tag">/&gt;</span>
					</pre>
					<p></p>
				</div>

				<div class="section" title="Channel Interceptor Configuration">
					<div class="titlepage">
						<div>
							<div>
								<h4 class="title">
									<a name="channel-configuration-interceptors"></a>Channel
									Interceptor Configuration
								</h4>
							</div>
						</div>
					</div>

					<p>
						Message channels may also have interceptors as described in <a
							class="xref"
							href="messaging-channels-section.html#channel-interceptors"
							title="3.1.3&nbsp;Channel Interceptors">Section&nbsp;3.1.3,
							&#8220;Channel Interceptors&#8221;</a>. The &lt;interceptors/&gt;
						sub-element can be added within &lt;channel/&gt; (or the more
						specific element types). Provide the
						<code class="code">ref</code>
						attribute to reference any Spring-managed object that implements
						the
						<code class="interfacename">ChannelInterceptor</code>
						interface:
					</p>
					<pre class="programlisting">
						<span class="hl-tag">&lt;int:channel</span> <span
							class="hl-attribute">id</span>=<span class="hl-value">"exampleChannel"</span><span
							class="hl-tag">&gt;</span>
    <span class="emphasis"><em>&lt;int:interceptors&gt;
        &lt;ref bean="trafficMonitoringInterceptor"/&gt;
    &lt;/int:interceptors&gt;</em></span>
<span class="hl-tag">&lt;/int:channel&gt;</span>
					</pre>
					<p>In general, it is a good idea to define the interceptor
						implementations in a separate location since they usually provide
						common behavior that can be reused across multiple channels.</p>
				</div>

				<div class="section"
					title="Global Channel Interceptor Configuration">
					<div class="titlepage">
						<div>
							<div>
								<h4 class="title">
									<a name="global-channel-configuration-interceptors"></a>Global
									Channel Interceptor Configuration
								</h4>
							</div>
						</div>
					</div>




					<p>
						Channel Interceptors provide a clean and concise way of applying
						cross-cutting behavior per individual channel. If the same
						behavior should be applied on multiple channels, configuring the
						same set of interceptors for each channel <span class="emphasis"><em>would
								not be</em></span> the most efficient way. To avoid repeated configuration
						while also enabling interceptors to apply to multiple channels,
						Spring Integration provides <span class="emphasis"><em>Global
								Interceptors</em></span>. Look at the example below:
					</p>
					<pre class="programlisting">
						<span class="hl-tag">&lt;int:channel-interceptor</span> <span
							class="hl-attribute">pattern</span>=<span class="hl-value">"input*, bar*, foo"</span> <span
							class="hl-attribute">order</span>=<span class="hl-value">"3"</span><span
							class="hl-tag">&gt;</span>
    <span class="hl-tag">&lt;bean</span> <span class="hl-attribute">class</span>=<span
							class="hl-value">"foo.barSampleInterceptor"</span><span
							class="hl-tag">/&gt;</span>
<span class="hl-tag">&lt;/int:channel-interceptor&gt;</span>
					</pre>
					<p>or</p>
					<pre class="programlisting">
						<span class="hl-tag">&lt;int:channel-interceptor</span> <span
							class="hl-attribute">ref</span>=<span class="hl-value">"myInterceptor"</span> <span
							class="hl-attribute">pattern</span>=<span class="hl-value">"input*, bar*, foo"</span> <span
							class="hl-attribute">order</span>=<span class="hl-value">"3"</span><span
							class="hl-tag">/&gt;</span>

<span class="hl-tag">&lt;bean</span> <span class="hl-attribute">id</span>=<span
							class="hl-value">"myInterceptor"</span> <span
							class="hl-attribute">class</span>=<span class="hl-value">"foo.barSampleInterceptor"</span><span
							class="hl-tag">/&gt;</span>
					</pre>
					<p>
						Each &lt;channel-interceptor/&gt; element allows you to define a
						global interceptor which will be applied on all channels that
						match any patterns defined via the
						<code class="code">pattern</code>
						attribute. In the above case the global interceptor will be
						applied on the 'foo' channel and all other channels that begin
						with 'bar' or 'input'. The <span class="emphasis"><em>order</em></span>
						attribute allows you to manage where this interceptor will be
						injected if there are multiple interceptors on a given channel.
						For example, channel 'inputChannel' could have individual
						interceptors configured locally (see below):
					</p>
					<pre class="programlisting">
						<span class="hl-tag">&lt;int:channel</span> <span
							class="hl-attribute">id</span>=<span class="hl-value">"inputChannel"</span><span
							class="hl-tag">&gt;</span>&nbsp;
  <span class="hl-tag">&lt;int:interceptors&gt;</span>
    <span class="hl-tag">&lt;int:wire-tap</span> <span
							class="hl-attribute">channel</span>=<span class="hl-value">"logger"</span><span
							class="hl-tag">/&gt;</span>&nbsp;
  <span class="hl-tag">&lt;/int:interceptors&gt;</span>
<span class="hl-tag">&lt;/int:channel&gt;</span>
					</pre>
					<p>
						A reasonable question is how will a global interceptor be injected
						in relation to other interceptors configured locally or through
						other global interceptor definitions? The current implementation
						provides a very simple mechanism for defining the order of
						interceptor execution. A positive number in the
						<code class="code">order</code>
						attribute will ensure interceptor injection after any existing
						interceptors and a negative number will ensure that the
						interceptor is injected before existing interceptors. This means
						that in the above example, the global interceptor will be injected
						<span class="emphasis"><em>AFTER</em></span> (since its order is
						greater than 0) the 'wire-tap' interceptor configured locally. If
						there were another global interceptor with a matching
						<code class="code">pattern</code>
						, its order would be determined by comparing the values of the
						<code class="code">order</code>
						attribute. To inject a global interceptor <span class="emphasis"><em>BEFORE</em></span>
						the existing interceptors, use a negative value for the
						<code class="code">order</code>
						attribute.
					</p>
					<div class="note" title="Note"
						style="margin-left: 0.5in; margin-right: 0.5in;">
						<table border="0" summary="Note">
							<tr>
								<td rowspan="2" align="center" valign="top" width="25"><img
									alt="[Note]" src="images/admon/note.png"></td>
								<th align="left">Note</th>
							</tr>
							<tr>
								<td align="left" valign="top">Note that both the <code
										class="code">order</code> and <code class="code">pattern</code>
									attributes are optional. The default value for <code
										class="code">order</code> will be 0 and for <code class="code">pattern</code>,
									the default is '*' (to match all channels).
								</td>
							</tr>
						</table>
					</div>
				</div>

				<div class="section" title="Wire Tap">
					<div class="titlepage">
						<div>
							<div>
								<h4 class="title">
									<a name="channel-wiretap"></a>Wire Tap
								</h4>
							</div>
						</div>
					</div>

					<p>
						As mentioned above, Spring Integration provides a simple <span
							class="emphasis"><em>Wire Tap</em></span> interceptor out of the
						box. You can configure a <span class="emphasis"><em>Wire
								Tap</em></span> on any channel within an &lt;interceptors/&gt; element. This
						is especially useful for debugging, and can be used in conjunction
						with Spring Integration's logging Channel Adapter as follows:
					</p>
					<pre class="programlisting"> <span class="hl-tag">&lt;int:channel</span> <span
							class="hl-attribute">id</span>=<span class="hl-value">"in"</span><span
							class="hl-tag">&gt;</span>
     <span class="hl-tag">&lt;int:interceptors&gt;</span>
         <span class="hl-tag">&lt;int:wire-tap</span> <span
							class="hl-attribute">channel</span>=<span class="hl-value">"logger"</span><span
							class="hl-tag">/&gt;</span>
     <span class="hl-tag">&lt;/int:interceptors&gt;</span>
 <span class="hl-tag">&lt;/int:channel&gt;</span>

 <span class="hl-tag">&lt;int:logging-channel-adapter</span> <span
							class="hl-attribute">id</span>=<span class="hl-value">"logger"</span> <span
							class="hl-attribute">level</span>=<span class="hl-value">"DEBUG"</span><span
							class="hl-tag">/&gt;</span>
					</pre>
					<p></p>
					<div class="tip" title="Tip"
						style="margin-left: 0.5in; margin-right: 0.5in;">
						<table border="0" summary="Tip">
							<tr>
								<td rowspan="2" align="center" valign="top" width="25"><img
									alt="[Tip]" src="images/admon/tip.png"></td>
								<th align="left">Tip</th>
							</tr>
							<tr>
								<td align="left" valign="top">The 'logging-channel-adapter'
									also accepts an 'expression' attribute so that you can evaluate
									a SpEL expression against 'payload' and/or 'headers' variables.
									Alternatively, to simply log the full Message toString()
									result, provide a value of "true" for the 'log-full-message'
									attribute. That is <code class="code">false</code> by default
									so that only the payload is logged. Setting that to <code
										class="code">true</code> enables logging of all headers in
									addition to the payload. The 'expression' option does provide
									the most flexibility, however (e.g.
									expression="payload.user.name").
								</td>
							</tr>
						</table>
					</div>
					<p></p>

					<p>
						<span class="emphasis"><em>A little more on Wire Tap</em></span>
					</p>
					<p>
						One of the common misconceptions about the wire tap and other
						similar components (<a class="xref"
							href="message-publishing.html#message-publishing-config"
							title="A.1&nbsp;Message Publishing Configuration">Section&nbsp;A.1,
							&#8220;Message Publishing Configuration&#8221;</a>) is that they are
						automatically asynchronous in nature. Wire-tap as a component is
						not invoked asynchronously be default. Instead, Spring Integration
						focuses on a single unified approach to configuring asynchronous
						behavior: the Message Channel. What makes certain parts of the
						message flow <span class="emphasis"><em>sync</em></span> or <span
							class="emphasis"><em>async</em></span> is the type of <span
							class="emphasis"><em>Message Channel</em></span> that has been
						configured within that flow. That is one of the primary benefits
						of the Message Channel abstraction. From the inception of the
						framework, we have always emphasized the need and the value of the
						<span class="emphasis"><em>Message Channel</em></span> as a
						first-class citizen of the framework. It is not just an internal,
						implicit realization of the EIP pattern, it is fully exposed as a
						configurable component to the end user. So, the Wire-tap component
						is ONLY responsible for performing the following 3 tasks:
					</p>
					<div class="itemizedlist">
						<ul class="itemizedlist" type="disc">
							<li class="listitem">
								<p>intercept a message flow by tapping into a channel (e.g.,
									channelA)</p>
							</li>
							<li class="listitem">
								<p>grab each message</p>
							</li>
							<li class="listitem">
								<p>send the message to another channel (e.g., channelB)</p>
							</li>
						</ul>
					</div>
					<p>

						It is essentially a variation of the Bridge, but it is
						encapsulated within a channel definition (and hence easier to
						enable and disable without disrupting a flow). Also, unlike the
						bridge, it basically forks another message flow. Is that flow <span
							class="emphasis"><em>synchronous</em></span> or <span
							class="emphasis"><em>asynchronous</em></span>? The answer simply
						depends on the type of <span class="emphasis"><em>Message
								Channel</em></span> that 'channelB' is. And, now you know that we have: <span
							class="emphasis"><em>Direct Channel</em></span>, <span
							class="emphasis"><em>Pollable Channel</em></span>, and <span
							class="emphasis"><em>Executor Channel</em></span> as options. The
						last two do break the thread boundary making communication via
						such channels <span class="emphasis"><em>asynchronous</em></span>
						simply because the dispatching of the message from that channel to
						its subscribed handlers happens on a different thread than the one
						used to send the message to that channel. That is what is going to
						make your wire-tap flow <span class="emphasis"><em>sync</em></span>
						or <span class="emphasis"><em>async</em></span>. It is consistent
						with other components within the framework (e.g., Message
						Publisher) and actually brings a level of consistency and
						simplicity by sparing you from worrying in advance (other than
						writing thread safe code) whether a particular piece of code
						should be implemented as <span class="emphasis"><em>sync</em></span>
						or <span class="emphasis"><em>async</em></span>. The actual wiring
						of two pieces of code (component A and component B) via <span
							class="emphasis"><em>Message Channel</em></span> is what makes
						their collaboration <span class="emphasis"><em>sync</em></span> or
						<span class="emphasis"><em>async</em></span>. You may even want to
						change from <span class="emphasis"><em>sync</em></span> to <span
							class="emphasis"><em>async</em></span> in the future and <span
							class="emphasis"><em>Message Channel</em></span> is what's going
						to allow you to do it swiftly without ever touching the code.
					</p>

					<p>One final point regarding the Wire Tap is that, despite the
						rationale provided above for not being async be default, one
						should keep in mind it is usually desirable to hand off the
						Message as soon as possible. Therefore, it would be quite common
						to use an asynchronous channel option as the wire-tap's outbound
						channel. Nonetheless, another reason that we do not enforce
						asynchronous behavior by default is that you might not want to
						break a transactional boundary. Perhaps you are using the Wire Tap
						for auditing purposes, and you DO want the audit Messages to be
						sent within the original transaction. As an example, you might
						connect the wire-tap to a JMS outbound-channel-adapter. That way,
						you get the best of both worlds: 1) the sending of a JMS Message
						can occur within the transaction while 2) it is still a
						"fire-and-forget" action thereby preventing any noticeable delay
						in the main message flow.</p>
				</div>
				<div class="section" title="Global Wire Tap Configuration">
					<div class="titlepage">
						<div>
							<div>
								<h4 class="title">
									<a name="channel-global-wiretap"></a>Global Wire Tap
									Configuration
								</h4>
							</div>
						</div>
					</div>

					<p>
						It is possible to configure a global wire tap as a special case of
						the <a class="xref"
							href="messaging-channels-section.html#global-channel-configuration-interceptors"
							title="Global Channel Interceptor Configuration">Global
							Channel Interceptor</a>. Simply configure a top level
						<code class="code">wire-tap</code>
						element. Now, in addition to the normal
						<code class="code">wire-tap</code>
						namespace support, the
						<code class="code">pattern</code>
						and
						<code class="code">order</code>
						attributes are supported and work in exactly the same way as with
						the
						<code class="code">channel-interceptor</code>
					</p>
					<pre class="programlisting">
						<span class="hl-tag">&lt;int:wire-tap</span> <span
							class="hl-attribute">pattern</span>=<span class="hl-value">"input*, bar*, foo"</span> <span
							class="hl-attribute">order</span>=<span class="hl-value">"3"</span> <span
							class="hl-attribute">channel</span>=<span class="hl-value">"wiretapChannel"</span><span
							class="hl-tag">/&gt;</span>
					</pre>
					<p></p>
					<div class="tip" title="Tip"
						style="margin-left: 0.5in; margin-right: 0.5in;">
						<table border="0" summary="Tip">
							<tr>
								<td rowspan="2" align="center" valign="top" width="25"><img
									alt="[Tip]" src="images/admon/tip.png"></td>
								<th align="left">Tip</th>
							</tr>
							<tr>
								<td align="left" valign="top">A global wire tap provides a
									convenient way to configure a single channel wire tap
									externally without modifying the existing channel
									configuration. Simply set the <code class="code">pattern</code>
									attribute to the target channel name. For example, This
									technique may be used to configure a test case to verify
									messages on a channel.
								</td>
							</tr>
						</table>
					</div>
				</div>


			</div>


			<div class="section" title="3.1.6&nbsp;Special Channels">
				<div class="titlepage">
					<div>
						<div>
							<h3 class="title">
								<a name="channel-special-channels"></a>3.1.6&nbsp;Special
								Channels
							</h3>
						</div>
					</div>
				</div>

				<p>
					If namespace support is enabled, there are two special channels
					defined within the application context by default:
					<code class="code">errorChannel</code>
					and
					<code class="code">nullChannel</code>
					. The 'nullChannel' acts like
					<code class="code">/dev/null</code>
					, simply logging any Message sent to it at DEBUG level and
					returning immediately. Any time you face channel resolution errors
					for a reply that you don't care about, you can set the affected
					component's
					<code class="code">output-channel</code>
					attribute to 'nullChannel' (the name 'nullChannel' is reserved
					within the application context). The 'errorChannel' is used
					internally for sending error messages and may be overridden with a
					custom configuration. This is discussed in greater detail in <a
						class="xref" href="configuration.html#namespace-errorhandler"
						title="E.4&nbsp;Error Handling">Section&nbsp;E.4, &#8220;Error
						Handling&#8221;</a>.
				</p>
			</div>
		</div>
		<div class="section" title="3.2&nbsp;Poller (Polling Consumer)">
			<div class="titlepage">
				<div>
					<div>
						<h2 class="title" style="clear: both">
							<a name="polling-consumer"></a>3.2&nbsp;Poller (Polling Consumer)
						</h2>
					</div>
				</div>
			</div>

			<p>When Message Endpoints (Channel Adapters) are connected to
				channels and instantiated, they produce one of the following 2
				instances:</p>
			<div class="itemizedlist">
				<ul class="itemizedlist" type="disc">
					<li class="listitem"><a class="ulink"
						href="http://static.springsource.org/spring-integration/api/org/springframework/integration/endpoint/PollingConsumer.html"
						target="_top">PollingConsumer</a></li>
					<li class="listitem"><a class="ulink"
						href="http://static.springsource.org/spring-integration/api/org/springframework/integration/endpoint/EventDrivenConsumer.html"
						target="_top">EventDrivenConsumer</a></li>
				</ul>
			</div>
			<p>
				The actual implementation depends on which type of channel these
				Endpoints are connected to. A channel adapter connected to a channel
				that implements the
				<code class="interfacename">
					<a class="ulink"
						href="http://static.springsource.org/spring-integration/api/org/springframework/integration/core/SubscribableChannel.html"
						target="_top">org.springframework.integration.core.SubscribableChannel</a>
				</code>
				interface will produce an instance of
				<code class="classname">EventDrivenConsumer</code>
				. On the other hand, a channel adapter connected to a channel that
				implements the
				<code class="interfacename">
					<a class="ulink"
						href="http://static.springsource.org/spring-integration/api/org/springframework/integration/core/PollableChannel.html"
						target="_top">org.springframework.integration.core.PollableChannel</a>
				</code>
				interface (e.g. a QueueChannel) will produce an instance of
				<code class="classname">PollingConsumer</code>
				.
			</p>
			<p>Polling Consumers allow Spring Integration components to
				actively poll for Messages, rather than to process Messages in an
				event-driven manner.</p>
			<p>They represent a critical cross cutting concern in many
				messaging scenarios. In Spring Integration, Polling Consumers are
				based on the pattern with the same name, which is described in the
				book "Enterprise Integration Patterns" by Gregor Hohpe and Bobby
				Woolf. You can find a description of the pattern on the book's
				website at:</p>
			<div class="itemizedlist">
				<ul class="itemizedlist" type="disc">
					<li class="listitem"><a class="ulink"
						href="http://www.enterpriseintegrationpatterns.com/PollingConsumer.html"
						target="_top">
							http://www.enterpriseintegrationpatterns.com/PollingConsumer.html
					</a></li>
				</ul>
			</div>
			<p>
				Furthermore, in Spring Integration a second variation of the Polling
				Consumer pattern exists. When Inbound Channel Adapters are being
				used, these adapters are often wrapped by a
				<code class="classname">SourcePollingChannelAdapter</code>
				. For example, when retrieving messages from a remote FTP Server
				location, the adapter described in <a class="xref"
					href="ftp.html#ftp-inbound"
					title="13.3&nbsp;FTP Inbound Channel Adapter">Section&nbsp;13.3,
					&#8220;FTP Inbound Channel Adapter&#8221;</a> is configured with a <span
					class="emphasis"><em>poller</em></span> to retrieve messages
				periodically. So, when components are configured with Pollers, the
				resulting instances are of one of the following types:
			</p>
			<div class="itemizedlist">
				<ul class="itemizedlist" type="disc">
					<li class="listitem"><a class="ulink"
						href="http://static.springsource.org/spring-integration/api/org/springframework/integration/endpoint/PollingConsumer.html"
						target="_top">PollingConsumer</a></li>
					<li class="listitem"><a class="ulink"
						href="http://static.springsource.org/spring-integration/api/org/springframework/integration/endpoint/SourcePollingChannelAdapter.html"
						target="_top">SourcePollingChannelAdapter</a></li>
				</ul>
			</div>
			<p>This means, Pollers are used in both inbound and outbound
				messaging scenarios. Here are some use-cases that illustrate the
				scenarios in which Pollers are used:</p>
			<div class="itemizedlist">
				<ul class="itemizedlist" type="disc">
					<li class="listitem">Polling certain external systems such as
						FTP Servers, Databases, Web Services</li>
					<li class="listitem">Polling internal (pollable) Message
						Channels</li>
					<li class="listitem">Polling internal services (E.g.
						repeatedly execute methods on a Java class)</li>
				</ul>
			</div>
			<p>
				This chapter is meant to only give a high-level overview regarding
				Polling Consumers and how they fit into the concept of message
				channels - <a class="xref"
					href="messaging-channels-section.html#channel"
					title="3.1&nbsp;Message Channels">Section&nbsp;3.1,
					&#8220;Message Channels&#8221;</a> and channel adapters - <a
					class="xref" href="messaging-channels-section.html#channel-adapter"
					title="3.3&nbsp;Channel Adapter">Section&nbsp;3.3,
					&#8220;Channel Adapter&#8221;</a>. For more in-depth information
				regarding Messaging Endpoints in general and Polling Consumers in
				particular, please see <a class="xref"
					href="messaging-endpoints-chapter.html#endpoint"
					title="7.1&nbsp;Message Endpoints">Section&nbsp;7.1,
					&#8220;Message Endpoints&#8221;</a>.
			</p>

		</div>
		<div class="section" title="3.3&nbsp;Channel Adapter">
			<div class="titlepage">
				<div>
					<div>
						<h2 class="title" style="clear: both">
							<a name="channel-adapter"></a>3.3&nbsp;Channel Adapter
						</h2>
					</div>
				</div>
			</div>

			<p>A Channel Adapter is a Message Endpoint that enables
				connecting a single sender or receiver to a Message Channel. Spring
				Integration provides a number of adapters out of the box to support
				various transports, such as JMS, File, HTTP, Web Services, Mail, and
				more. Those will be discussed in upcoming chapters of this reference
				guide. However, this chapter focuses on the simple but flexible
				Method-invoking Channel Adapter support. There are both inbound and
				outbound adapters, and each may be configured with XML elements
				provided in the core namespace. These provide an easy way to extend
				Spring Integration as long as you have a method that can be invoked
				as either a source or destination.</p>

			<div class="section"
				title="3.3.1&nbsp;Configuring An Inbound Channel Adapter">
				<div class="titlepage">
					<div>
						<div>
							<h3 class="title">
								<a name="channel-adapter-namespace-inbound"></a>3.3.1&nbsp;Configuring
								An Inbound Channel Adapter
							</h3>
						</div>
					</div>
				</div>

				<p>
					An "inbound-channel-adapter" element can invoke any method on a
					Spring-managed Object and send a non-null return value to a
					<code class="interfacename">MessageChannel</code>
					after converting it to a
					<code class="classname">Message</code>
					. When the adapter's subscription is activated, a poller will
					attempt to receive messages from the source. The poller will be
					scheduled with the
					<code class="interfacename">TaskScheduler</code>
					according to the provided configuration. To configure the polling
					interval or cron expression for an individual channel-adapter,
					provide a 'poller' element with one of the scheduling attributes,
					such as 'fixed-rate' or 'cron'.
				</p>
				<pre class="programlisting">
					<span class="hl-tag">&lt;int:inbound-channel-adapter</span> <span
						class="hl-attribute">ref</span>=<span class="hl-value">"source1"</span> <span
						class="hl-attribute">method</span>=<span class="hl-value">"method1"</span> <span
						class="hl-attribute">channel</span>=<span class="hl-value">"channel1"</span><span
						class="hl-tag">&gt;</span>
    <span class="hl-tag">&lt;int:poller</span> <span
						class="hl-attribute">fixed-rate</span>=<span class="hl-value">"5000"</span><span
						class="hl-tag">/&gt;</span>
<span class="hl-tag">&lt;/int:inbound-channel-adapter&gt;</span>

<span class="hl-tag">&lt;int:inbound-channel-adapter</span> <span
						class="hl-attribute">ref</span>=<span class="hl-value">"source2"</span> <span
						class="hl-attribute">method</span>=<span class="hl-value">"method2"</span> <span
						class="hl-attribute">channel</span>=<span class="hl-value">"channel2"</span><span
						class="hl-tag">&gt;</span>
    <span class="hl-tag">&lt;int:poller</span> <span
						class="hl-attribute">cron</span>=<span class="hl-value">"30 * 9-17 * * MON-FRI"</span><span
						class="hl-tag">/&gt;</span>
<span class="hl-tag">&lt;/int:channel-adapter&gt;</span>
				</pre>
				<p></p>
				<div class="note" title="Note"
					style="margin-left: 0.5in; margin-right: 0.5in;">
					<table border="0" summary="Note">
						<tr>
							<td rowspan="2" align="center" valign="top" width="25"><img
								alt="[Note]" src="images/admon/note.png"></td>
							<th align="left">Note</th>
						</tr>
						<tr>
							<td align="left" valign="top">
								<p>
									If no poller is provided, then a single default poller must be
									registered within the context. See <a class="xref"
										href="messaging-endpoints-chapter.html#endpoint-namespace"
										title="7.1.4&nbsp;Namespace Support">Section&nbsp;7.1.4,
										&#8220;Namespace Support&#8221;</a> for more detail.
								</p>
							</td>
						</tr>
					</table>
				</div>
				<div class="important" title="Important"
					style="margin-left: 0.5in; margin-right: 0.5in;">
					<table border="0" summary="Important">
						<tr>
							<td rowspan="2" align="center" valign="top" width="25"><img
								alt="[Important]" src="images/admon/important.png"></td>
							<th align="left">Important</th>
						</tr>
						<tr>
							<td align="left" valign="top">
								<p>
									<span class="emphasis"><em>Poller Configuration</em></span>
								</p>
								<p>
									Some
									<code class="code">inbound-channel-adapter</code>
									types are backed by a
									<code class="classname">SourcePollingChannelAdapter</code>
									which means they contain Poller configuration which will poll
									the
									<code class="classname">MessageSource</code>
									(invoke a custom method which produces the value that becomes a
									<code class="classname">Message</code>
									payload) based on the configuration specified in the Poller.
								</p>
								<p>For example:</p> <pre class="programlisting">
									<span class="hl-tag">&lt;int:poller</span> <span
										class="hl-attribute">max-messages-per-poll</span>=<span
										class="hl-value">"1"</span> <span class="hl-attribute">fixed-rate</span>=<span
										class="hl-value">"1000"</span><span class="hl-tag">/&gt;</span>

<span class="hl-tag">&lt;int:poller</span> <span class="hl-attribute">max-messages-per-poll</span>=<span
										class="hl-value">"10"</span> <span class="hl-attribute">fixed-rate</span>=<span
										class="hl-value">"1000"</span><span class="hl-tag">/&gt;</span>
								</pre>
								<p>
									In the the first configuration the polling task will be invoked
									once per poll and during such task (poll) the method (which
									results in the production of the Message) will be invoked once
									based on the
									<code class="code">max-messages-per-poll</code>
									attribute value. In the second configuration the polling task
									will be invoked 10 times per poll or until it returns 'null'
									thus possibly producing 10 Messages per poll while each poll
									happens at 1 second intervals. However what if the
									configuration looks like this:
								</p> <pre class="programlisting">
									<span class="hl-tag">&lt;int:poller</span> <span
										class="hl-attribute">fixed-rate</span>=<span class="hl-value">"1000"</span><span
										class="hl-tag">/&gt;</span>
								</pre>
								<p>
									Note there is no
									<code class="code">max-messages-per-poll</code>
									specified. As you'll learn later the identical poller
									configuration in the
									<code class="classname">PollingConsumer</code>
									(e.g., service-activator, filter, router etc.) would have a
									default value of -1 for
									<code class="code">max-messages-per-poll</code>
									which means "execute poling task non-stop unless polling method
									returns null (e.g., no more Messages in the QueueChannel)" and
									then sleep for 1 second.
								</p>
								<p>
									However in the SourcePollingChannelAdapter it is a bit
									different. The default value for
									<code class="code">max-messages-per-poll</code>
									will be set to 1 by default unless you explicitly set it to a
									negative value (e.g., -1). It is done so to make sure that
									poller can react to a LifeCycle events (e.g., start/stop) and
									prevent it from potentially spinning in the infinite loop if
									the implementation of the custom method of the
									<code class="classname">MessageSource</code>
									has a potential to never return null and happened to be
									non-interruptible.
								</p>
								<p>
									However if you are sure that your method can return null and
									you need the behavior where you want to poll for as many
									sources as available per each poll, then you should explicitly
									set
									<code class="code">max-messages-per-poll</code>
									to negative value.
								</p> <pre class="programlisting">
									<span class="hl-tag">&lt;int:poller</span> <span
										class="hl-attribute">max-messages-per-poll</span>=<span
										class="hl-value">"-1"</span> <span class="hl-attribute">fixed-rate</span>=<span
										class="hl-value">"1000"</span><span class="hl-tag">/&gt;</span>
								</pre>
							</td>
						</tr>
					</table>
				</div>
			</div>

			<div class="section"
				title="3.3.2&nbsp;Configuring Outbound Channel Adapter">
				<div class="titlepage">
					<div>
						<div>
							<h3 class="title">
								<a name="channel-adapter-namespace-outbound"></a>3.3.2&nbsp;Configuring
								Outbound Channel Adapter
							</h3>
						</div>
					</div>
				</div>

				<p>
					An "outbound-channel-adapter" element can also connect a
					<code class="interfacename">MessageChannel</code>
					to any POJO consumer method that should be invoked with the payload
					of Messages sent to that channel.
				</p>
				<pre class="programlisting">
					<span class="hl-tag">&lt;int:outbound-channel-adapter</span> <span
						class="hl-attribute">channel</span>=<span class="hl-value">"channel1"</span> <span
						class="hl-attribute">ref</span>=<span class="hl-value">"target"</span> <span
						class="hl-attribute">method</span>=<span class="hl-value">"handle"</span><span
						class="hl-tag">/&gt;</span>

<span class="hl-tag">&lt;beans:bean</span> <span class="hl-attribute">id</span>=<span
						class="hl-value">"target"</span> <span class="hl-attribute">class</span>=<span
						class="hl-value">"org.Foo"</span><span class="hl-tag">/&gt;</span>
</pre>
				<p>

					If the channel being adapted is a
					<code class="interfacename">PollableChannel</code>
					, provide a poller sub-element:
				</p>
				<pre class="programlisting">
					<span class="hl-tag">&lt;int:outbound-channel-adapter</span> <span
						class="hl-attribute">channel</span>=<span class="hl-value">"channel2"</span> <span
						class="hl-attribute">ref</span>=<span class="hl-value">"target"</span> <span
						class="hl-attribute">method</span>=<span class="hl-value">"handle"</span><span
						class="hl-tag">&gt;</span>
    <span class="emphasis"><em>&lt;int:poller fixed-rate="3000"/&gt;
</em></span>
<span class="hl-tag">&lt;/int:outbound-channel-adapter&gt;</span>

<span class="hl-tag">&lt;beans:bean</span> <span class="hl-attribute">id</span>=<span
						class="hl-value">"target"</span> <span class="hl-attribute">class</span>=<span
						class="hl-value">"org.Foo"</span><span class="hl-tag">/&gt;</span>
</pre>
				<p></p>
				<p>
					Using a "ref" attribute is generally recommended if the POJO
					consumer implementation can be reused in other
					<code class="code">&lt;outbound-channel-adapter&gt;</code>
					definitions. However if the consumer implementation is only
					referenced by a single definition of the
					<code class="code">&lt;outbound-channel-adapter&gt;</code>
					, you can define it as inner bean:
				</p>
				<pre class="programlisting">
					<span class="hl-tag">&lt;int:outbound-channel-adapter</span> <span
						class="hl-attribute">channel</span>=<span class="hl-value">"channel"</span> <span
						class="hl-attribute">method</span>=<span class="hl-value">"handle"</span><span
						class="hl-tag">&gt;</span>
        <span class="hl-tag">&lt;beans:bean</span> <span
						class="hl-attribute">class</span>=<span class="hl-value">"org.Foo"</span><span
						class="hl-tag">/&gt;</span>
    
<span class="hl-tag">&lt;/int:outbound-channel-adapter&gt;</span>
</pre>
				<p></p>
				<div class="note" title="Note"
					style="margin-left: 0.5in; margin-right: 0.5in;">
					<table border="0" summary="Note">
						<tr>
							<td rowspan="2" align="center" valign="top" width="25"><img
								alt="[Note]" src="images/admon/note.png"></td>
							<th align="left">Note</th>
						</tr>
						<tr>
							<td align="left" valign="top">
								<p>
									Using both the "ref" attribute and an inner handler definition
									in the same
									<code class="code">&lt;outbound-channel-adapter&gt;</code>
									configuration is not allowed as it creates an ambiguous
									condition. Such a configuration will result in an Exception
									being thrown.
								</p>
							</td>
						</tr>
					</table>
				</div>
				<p>
					Any Channel Adapter can be created without a "channel" reference in
					which case it will implicitly create an instance of
					<code class="classname">DirectChannel</code>
					. The created channel's name will match the "id" attribute of the
					<code class="code">&lt;inbound-channel-adapter&gt;</code>
					or
					<code class="code">&lt;outbound-channel-adapter&gt;</code>
					element. Therefore, if the "channel" is not provided, the "id" is
					required.
				</p>
				<p>
					Like many other Spring Integration components, the
					<code class="code">&lt;inbound-channel-adapter&gt;</code>
					and
					<code class="code">&lt;outbound-channel-adapter&gt;</code>
					also provide support for SpEL expression evaluation. To use SpEL,
					provide the expression string via the 'expression' attribute
					instead of providing the 'ref' and 'method' attributes that are
					used for method-invocation on a bean. When an Expression is
					evaluated, it follows the same contract as method-invocation where:
					the <span class="emphasis"><em>expression</em></span> for an
					<code class="code">&lt;inbound-channel-adapter&gt;</code>
					will generate a message anytime the evaluation result is a <span
						class="emphasis"><em>non-null</em></span> value, while the <span
						class="emphasis"><em>expression</em></span> for an
					<code class="code">&lt;outbound-channel-adapter&gt;</code>
					must be the equivalent of a <span class="emphasis"><em>void</em></span>
					returning method invocation.
				</p>
			</div>

		</div>
		<div class="section" title="3.4&nbsp;Messaging Bridge">
			<div class="titlepage">
				<div>
					<div>
						<h2 class="title" style="clear: both">
							<a name="bridge"></a>3.4&nbsp;Messaging Bridge
						</h2>
					</div>
				</div>
			</div>


			<div class="section" title="3.4.1&nbsp;Introduction">
				<div class="titlepage">
					<div>
						<div>
							<h3 class="title">
								<a name="bridge-introduction"></a>3.4.1&nbsp;Introduction
							</h3>
						</div>
					</div>
				</div>

				<p>
					A Messaging Bridge is a relatively trivial endpoint that simply
					connects two Message Channels or Channel Adapters. For example, you
					may want to connect a
					<code class="interfacename">PollableChannel</code>
					to a
					<code class="interfacename">SubscribableChannel</code>
					so that the subscribing endpoints do not have to worry about any
					polling configuration. Instead, the Messaging Bridge provides the
					polling configuration.
				</p>
				<p>By providing an intermediary poller between two channels, a
					Messaging Bridge can be used to throttle inbound Messages. The
					poller's trigger will determine the rate at which messages arrive
					on the second channel, and the poller's "maxMessagesPerPoll"
					property will enforce a limit on the throughput.</p>
				<p>
					Another valid use for a Messaging Bridge is to connect two
					different systems. In such a scenario, Spring Integration's role
					would be limited to making the connection between these systems and
					managing a poller if necessary. It is probably more common to have
					at least a <span class="emphasis"><em>Transformer</em></span>
					between the two systems to translate between their formats, and in
					that case, the channels would be provided as the 'input-channel'
					and 'output-channel' of a Transformer endpoint. If data format
					translation is not required, the Messaging Bridge may indeed be
					sufficient.
				</p>
			</div>

			<div class="section" title="3.4.2&nbsp;Configuring Bridge">
				<div class="titlepage">
					<div>
						<div>
							<h3 class="title">
								<a name="bridge-namespace"></a>3.4.2&nbsp;Configuring Bridge
							</h3>
						</div>
					</div>
				</div>

				<p>The &lt;bridge&gt; element is used to create a Messaging
					Bridge between two Message Channels or Channel Adapters. Simply
					provide the "input-channel" and "output-channel" attributes:</p>
				<pre class="programlisting"> <span class="hl-tag">&lt;int:bridge</span> <span
						class="hl-attribute">input-channel</span>=<span class="hl-value">"input"</span> <span
						class="hl-attribute">output-channel</span>=<span class="hl-value">"output"</span><span
						class="hl-tag">/&gt;</span>
				</pre>
				<p>
					As mentioned above, a common use case for the Messaging Bridge is
					to connect a
					<code class="interfacename">PollableChannel</code>
					to a
					<code class="interfacename">SubscribableChannel</code>
					, and when performing this role, the Messaging Bridge may also
					serve as a throttler:
				</p>
				<pre class="programlisting"> <span class="hl-tag">&lt;int:bridge</span> <span
						class="hl-attribute">input-channel</span>=<span class="hl-value">"pollable"</span> <span
						class="hl-attribute">output-channel</span>=<span class="hl-value">"subscribable"</span><span
						class="hl-tag">&gt;</span>
     <span class="hl-tag">&lt;int:poller</span> <span
						class="hl-attribute">max-messages-per-poll</span>=<span
						class="hl-value">"10"</span> <span class="hl-attribute">fixed-rate</span>=<span
						class="hl-value">"5000"</span><span class="hl-tag">/&gt;</span>
 <span class="hl-tag">&lt;/int:bridge&gt;</span>
				</pre>
				<p></p>
				<p>Connecting Channel Adapters is just as easy. Here is a simple
					echo example between the "stdin" and "stdout" adapters from Spring
					Integration's "stream" namespace.</p>
				<pre class="programlisting"> <span class="hl-tag">&lt;int-stream:stdin-channel-adapter</span> <span
						class="hl-attribute">id</span>=<span class="hl-value">"stdin"</span><span
						class="hl-tag">/&gt;</span>

 <span class="hl-tag">&lt;int-stream:stdout-channel-adapter</span> <span
						class="hl-attribute">id</span>=<span class="hl-value">"stdout"</span><span
						class="hl-tag">/&gt;</span>

 <span class="hl-tag">&lt;int:bridge</span> <span class="hl-attribute">id</span>=<span
						class="hl-value">"echo"</span> <span class="hl-attribute">input-channel</span>=<span
						class="hl-value">"stdin"</span> <span class="hl-attribute">output-channel</span>=<span
						class="hl-value">"stdout"</span><span class="hl-tag">/&gt;</span>
				</pre>
				<p>Of course, the configuration would be similar for other
					(potentially more useful) Channel Adapter bridges, such as File to
					JMS, or Mail to File. The various Channel Adapters will be
					discussed in upcoming chapters.</p>
				<div class="note" title="Note"
					style="margin-left: 0.5in; margin-right: 0.5in;">
					<table border="0" summary="Note">
						<tr>
							<td rowspan="2" align="center" valign="top" width="25"><img
								alt="[Note]" src="images/admon/note.png"></td>
							<th align="left">Note</th>
						</tr>
						<tr>
							<td align="left" valign="top">
								<p>If no 'output-channel' is defined on a bridge, the reply
									channel provided by the inbound Message will be used, if
									available. If neither output or reply channel is available, an
									Exception will be thrown.</p>
							</td>
						</tr>
					</table>
				</div>
			</div>

		</div>

	</div>
	<div class="navfooter">
		<hr>
		<table width="100%" summary="Navigation footer">
			<tr>
				<td width="40%" align="left"><a accesskey="p"
					href="spring-integration-core-messaging.html">Prev</a>&nbsp;</td>
				<td width="20%" align="center"><a accesskey="u"
					href="spring-integration-core-messaging.html">Up</a></td>
				<td width="40%" align="right">&nbsp;<a accesskey="n"
					href="messaging-construction-chapter.html">Next</a></td>
			</tr>
			<tr>
				<td width="40%" align="left" valign="top">Part&nbsp;III.&nbsp;Core
					Messaging&nbsp;</td>
				<td width="20%" align="center"><a accesskey="h"
					href="index.html">Home</a></td>
				<td width="40%" align="right" valign="top">&nbsp;4.&nbsp;Message
					Construction</td>
			</tr>
		</table>
	</div>
	<!-- Begin 2nd Google code - a mod -->
	<script type="text/javascript">
		var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl."
				: "http://www.");
		document
				.write(unescape("%3Cscript src='"
						+ gaJsHost
						+ "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
	</script>
	<script type="text/javascript">
		var OrgTracker = _gat._getTracker("UA-2728886-2");
		OrgTracker._setDomainName("none");
		OrgTracker._setAllowLinker(true);
		OrgTracker._trackPageview();
	</script>
	<!-- End 2nd Google code -->


	<script type="text/javascript">
		function detectLastFrame() {
			var thisF = this.window;
			var allF = parent.top.frames;
			return allF[allF.length - 1] == thisF;
		}

		// Only inject the following code if this is a normal page or the last // frame of a frameset.
		if (parent.top.frames.length == 0 || detectLastFrame()) {
			// Inject the SpringSource search widget too.
			document
					.write(unescape("%3Cscript src='http://search.springsource.org/widget/searchtool.js' type='text/javascript'%3E%3C/script%3E"));
			// Inject the Eloqua code
			document
					.write(unescape("%3Cscript src='/elqNow/elqCfg.js' type='text/javascript'%3E%3C/script%3E"));
			document
					.write(unescape("%3Cscript src='/elqNow/elqImg.js' type='text/javascript'%3E%3C/script%3E"));

		}
	</script>
</body>
</html>